﻿using System;
using System.Collections.Generic;
using System.Windows.Media;

namespace FrontDisplay
{
    public class Fire : AnimatedBackground
    {
        private static int _maxGrow = 180;

        private bool _isGrowing = true;

        private int _bufWidth;
        private int _bufHeight;

        private int _grow;
        private double _growInc = 1;

        const int K1 = 20; //12
        const int K2 = 6; //4

        public Fire() : base(400, 40)
        {
            Initialize();
        }

        protected Fire(int imageWidth, int imageHeight, bool isGrowing) : base(imageWidth, imageHeight)
        {
            _isGrowing = isGrowing;
            Initialize();
        }

        private void Initialize()
        {
            _bufWidth = ImageWidth;
            _bufHeight = ImageHeight + 4;
            Buffer = new int[_bufHeight, _bufWidth];
        }

        public override string Name
        {
            get { return "Fire"; }
        }

        protected override void UpdateBuffer()
        {
            Random random = new Random(DateTime.Now.Millisecond);

            for (int i = 1; i < _bufHeight - 1; i++)
            {
                for (int j = 0; j < _bufWidth; j++)
                {
                    if (j == 0)
                    {
                        Buffer[i - 1, j] = (Buffer[i, j] + Buffer[i - 1, _bufWidth - 1] + Buffer[i, j + 1] + Buffer[i + 1, j]) >> 2;
                    }
                    else
                        if (j == (_bufWidth - 1))
                        {
                            Buffer[i - 1, j] = (Buffer[i, j] + Buffer[i, j - 1] + Buffer[i + 1, 0] + Buffer[i + 1, j]) >> 2;
                        }
                        else
                        {
                            Buffer[i - 1, j] = (Buffer[i, j] + Buffer[i, j - 1] + Buffer[i, j + 1] + Buffer[i + 1, j]) >> 2;
                        }

                    if (Buffer[i, j] >= K1)
                    {
                        Buffer[i, j] = Buffer[i, j] - K1;
                    }
                    else
                        if (Buffer[i, j] >= K2)
                        {
                            Buffer[i, j] = Buffer[i, j] - K2;
                        }
                        else
                        {
                            if (Buffer[i, j] > 0) Buffer[i, j]--;
                            if (Buffer[i, j] > 0) Buffer[i, j]--;
                            if (Buffer[i, j] > 0) Buffer[i, j]--;
                        }
                }

            }

            // new bottom margin
            int d = 0;
            for (var j = 0; j < _bufWidth; j++)
            {
                if (random.Next(10) < 5)
                {
                    d = random.Next(2) * 256;
                }
                Buffer[_bufHeight - 2, j] = d + _grow < 256 ? d + _grow : 255;
                Buffer[_bufHeight - 1, j] = d;
            }

            if (_isGrowing)
            {
                _grow += (int)_growInc;
                if (_grow > _maxGrow)
                {
                    _growInc = -random.Next(2);
                }
                else
                    if (_grow <= 0)
                    {
                        _growInc = +random.Next(2);
                    }
            }
        }

        public override void UpdateColors()
        {
            List<ColorStop> colors;

            //NOTE: Original fire colors.
            //colors = new List<ColorStop>
            //{
            //    new ColorStop(Colors.Black, 0),
            //    new ColorStop(Colors.Red, 70),
            //    new ColorStop(Colors.Yellow, 180),
            //    new ColorStop(Colors.White, 255)
            //};

            colors = new List<ColorStop>
            {
                new ColorStop(ThemeManager.BackgroundTop.Color, 0),
                new ColorStop(ThemeManager.Background.Color, 80),
                new ColorStop(ThemeManager.BackgroundBottom.Color, 255)
            };

            for (int i = 0; i < colors.Count - 1; i++)
            {
                SetPaletteColors(colors[i].Color, colors[i + 1].Color, colors[i].Pos, colors[i + 1].Pos);
            }
        }
    }

    internal class ColorStop
    {
        public int Pos { get; set; }
        public Color Color { get; set; }

        public ColorStop(Color color, int pos)
        {
            Pos = pos;
            Color = color;
        }
    }
}
